package mi.payment.utils.iso8583;

import android.text.TextUtils;

import java.io.UnsupportedEncodingException;
import java.util.Iterator;
import java.util.Map;

import lainey.ui.utils.LogUtil;
import mi.payment.CardType;
import mi.payment.Constant;
import mi.payment.bean.db.TradeData;
import mi.payment.db.dao.PayDetail;

public class FieldUtils {

    public static Map<String, MsgField> fillBeanByMap(TradeData tradeData, Map<String, MsgField> map) {
        PayDetail payDetail = tradeData.getPayDetail();
        Iterator iterator = map.entrySet().iterator();
        boolean next = iterator.hasNext();
        while (next) {
            Map.Entry<String, MsgField> fieldEntry = (Map.Entry<String, MsgField>) iterator.next();
            MsgField field = fieldEntry.getValue();
            String dataStr = field.getDataStr();
            byte[] dataBytes = field.getDataBytes();
            int fieldPos = field.getFieldPos();
            switch (fieldPos) {
                case 4: // 交易金额
                    long amount = Long.parseLong(dataStr);
                    payDetail.setAmount(amount);
                    break;
                case 12: // 交易时间
                    payDetail.setTradeTime(dataStr);
                    break;
                case 13: // 交易日期
                    payDetail.setTradeDate(dataStr);
                    break;
                case 15: // 清算日期
                    payDetail.setSettleDate(dataStr);
                    break;
                case 32: // 收单机构标识码
                    payDetail.setAcquiringBankSpotCode(dataStr);
                    break;
                case 37: // 检索参考号
                    payDetail.setReferNo(dataStr);
                    break;
                case 38: // 授权码
                    payDetail.setAuthNo(dataStr);
                    break;
                case 39:
                    payDetail.setTradeAnswerCode(dataStr);
                    break;
                case 44: // 收单机构代码与发卡机构代码
                    if (dataStr.length() >= 22) {
                        String temp = dataStr.substring(0, 8);
                        payDetail.setIssuingBankCode(temp);
                        temp = dataStr.substring(11, 19);
                        payDetail.setAcquiringBankCode(temp);
                    }
                    break;
                case 49: // 根据交易货币代码判断内外卡
                    String strCard = "";
                    try {
                        strCard = new String(dataBytes, "gbk");
                    } catch (UnsupportedEncodingException e) {
                        e.printStackTrace();
                    }
                    LogUtil.e(Constant.TAG, "49域 " + strCard);
                    if (strCard.length() > 0) {
                        boolean equals = strCard.equals("156");
                        if (equals) {
                            payDetail.setIsForeignCard(false);
                        } else {
                            payDetail.setIsForeignCard(true);
                        }
                    }
                    break;
                case 54: // 附加金额
                    int length = dataStr.length();
                    String balanceStr = dataStr.substring(length - 12);
                    long balance = Long.parseLong(balanceStr);
                    String CBit = dataStr.substring(length - 13, length - 12);
                    boolean equals = TextUtils.equals("C", CBit);
                    if (equals) {
                        payDetail.setAdditionalAmount(balance);
                    } else { // 负值
                        balance = -balance;
                        payDetail.setAdditionalAmount(balance);
                    }
                    break;
                case 55:
                    payDetail.setICC55(dataStr);
                    break;
                case 63: // 备注
                    try {
                        String referenceStr = new String(dataBytes, "GB2312");
                        if (referenceStr.length() > 3) {
                            referenceStr = referenceStr.substring(3); // 去掉63.1 如，cup
                            if (referenceStr.length() >= 60) {
                                referenceStr = referenceStr.substring(0, 60);
                            }
                            payDetail.setReference(referenceStr.trim());
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    break;
            }
            next = iterator.hasNext();
        }
        return map;
    }

    public static Map<String, MsgField> fillEachFieldValue(Map<String, MsgField> map, TradeData tradeData) {
        PayDetail payDetail = tradeData.getPayDetail();
        Iterator iterator = map.entrySet().iterator();
        boolean next = iterator.hasNext();
        while (next) {
            Map.Entry<String, MsgField> fieldEntry = (Map.Entry<String, MsgField>) iterator.next();
            MsgField field = fieldEntry.getValue();
            int cardType = payDetail.getCardType();
            int fieldPos = field.getFieldPos();
            switch (fieldPos) {
                case 2: // 主账号  当22域指明非磁条输入且可判卡号手机芯片交易该域必须出现,当22域前两位取值92时请求报文不需填入
                    if (CardType.NO_CARD.getValue() == payDetail.cardType) {
                        String cardNumber = payDetail.getCardNo();
                        field.setDataStr(cardNumber);
                    } else {
                        iterator.remove();
                    }
                    break;
                case 3: // 交易处理码
                    String code = payDetail.getProcessCode();
                    field.setDataStr(code);
                    break;
                case 4: // 交易金额
                    String amount = String.format("%012d", payDetail.amount);
                    field.setDataStr(amount);
                    break;
                case 11: // POS终端交易流水号
                    String voucherNo = payDetail.getVoucherNo();
                    field.setDataStr(voucherNo);
                    break;
                case 14: // 卡有效期
                    String expDate = payDetail.getEXPDate();
                    if (expDate != null && expDate.trim().length() > 0) {
                        field.setDataStr(expDate);
                    } else {
                        iterator.remove();
                    }
                    break;
                case 22: // 服务点输入方式码
                    String value;
                    if (CardType.MAGNETIC.getValue() == cardType) {     // 磁条
                        value = "02";
                    } else if (CardType.NFC.getValue() == cardType) {   // NFC
                        value = "07";
                    } else if (CardType.IC.getValue() == cardType) {    // IC
                        value = "05";
                    } else { // 手输卡号
                        value = "01";
                    }
                    if (payDetail.getPINCipher() != null && payDetail.getPINCipher().trim().length() > 0) {
                        value += "1";
                    } else {
                        // value += "2";
                        value += "1";
                    }
                    field.setDataStr(value);
                    break;
                case 23: // 卡片序列号 用于区别具有相同PAN的不同卡。只在IC卡交易时使用。
                    String cardSerialNo = payDetail.getCardSerialNo();
                    if (cardSerialNo != null && cardSerialNo.trim().length() > 0) {
                        field.setDataStr(cardSerialNo);
                    } else {
                        iterator.remove();
                    }
                    break;
                case 25: // 服务点条件码  普通消费交易和手机芯片交易填写00,订购消费交易填写08,分期付款交易交易填写64,积分消费交易填写65,手机无卡预约消费填写67
                    field.setDataStr("00");
                    break;
                case 26: // 服务点PIN获取码  22域指明PIN可输入且持卡人输入了PIN
                    if (payDetail.getPINCipher() != null && payDetail.getPINCipher().trim().length() > 0) {
                        field.setDataStr("12");
                    } else {
                        iterator.remove();
                    }
                    break;
                case 35: // 2磁道数据 22域磁条输入且存在二磁道信息,在手机芯片交易中如存在二磁道信息,则该域必须出现且被加密保护
                    String track2Cipher = tradeData.getCardInfo().getMAGCardInfo().getTrack2Cipher();
                    if (track2Cipher != null && track2Cipher.trim().length() > 0) {
                        field.setDataStr(track2Cipher);
                    } else {
                        iterator.remove();
                    }
                    break;
                case 36: // 3磁道数据  22域磁条输入且存在三磁道信息,在手机芯片交易中如存在三磁道信息,则该域必须出现且被加密保护
                    iterator.remove();
                    break;
                case 37: // 检索参考号
                    String originalReferNo = payDetail.getOriginalReferNo();
                    if (originalReferNo != null && originalReferNo.trim().length() > 0) {
                        field.setDataStr(originalReferNo);
                    } else {
                        iterator.remove();
                    }
                    break;
                case 38: // 授权码
                    String originalAuthNo = payDetail.getOriginalAuthNo();
                    if (originalAuthNo != null && originalAuthNo.trim().length() > 0) {
                        field.setDataStr(originalAuthNo);
                    } else {
                        iterator.remove();
                    }
                    break;
                case 39: // 请求时为冲正原因
                    String reason = payDetail.getReversalReason();
                    if (reason != null && reason.trim().length() > 0) {
                        field.setDataStr(reason);
                    } else {
                        iterator.remove();
                    }
                    break;
                case 41: // 受卡机终端标识码(终端代码)
                    String terminalNo = payDetail.getTerminalNo();
                    field.setDataStr(terminalNo);
                    break;
                case 42: // 受卡方标识码(商户代码)
                    String merchantNo = payDetail.getMerchantNo();
                    field.setDataStr(merchantNo);
                    break;
                case 49: // 交易货币代码
                    String currencyCode = payDetail.getCurrencyCode();
                    field.setDataStr(currencyCode);
                    break;
                case 52: // 个人标识码数据
                    String pinCipher = payDetail.getPINCipher();
                    if (pinCipher != null && pinCipher.trim().length() > 0) {
                        field.setDataStr(pinCipher);
                    } else {
                        iterator.remove();
                    }
                    break;
                case 53: // 安全控制信息 有安全要求或磁条信息出现时必选
                    if (payDetail.PINCipher != null && payDetail.PINCipher.trim().length() > 0) {
                        field.setDataStr(payDetail.tempKSN);
                    } else {
                        iterator.remove();
                    }
                    break;
                case 55: // IC卡数据域 以下子域中的M1、O1、C1仅当该交易为IC卡交易（不包括手机芯片交易）时有效,M2仅当交易为手机芯片交易时有效。
                    String icc55 = payDetail.getICC55();
                    if (icc55 != null && icc55.trim().length() > 0) {
                        // boolean visa = payDetail.CardNo.startsWith("4");
                        // boolean master = payDetail.CardNo.startsWith("5");
                        // if (visa) {
                        //     icc55 = "5F2A02045882021C00950580800480009A031811209C01009F02060000000100009F03060000000000009F100706010A03A0A0009F1A0204589F26083C9248B72C528C839F2701809F3303E0F8C89F34034203009F360200839F370421EAEB989F3501229F080200964F07A00000000310109F0E0500100000009F0F05B860FC98009F0D05B860BC88008407A00000000310109F0902008D5F340101";
                        // } else if (master) {
                        //     icc55 = "5F2A02045882023900950500000480009A031811209C01009F02060000000001009F03060000000000009F10120210A04001220000000000000000000000FF9F1A0204589F2608E4494721F3B288389F2701809F3303E0F8C89F34034203009F360200759F3704F1C2F8769F3501229F080200024F07A00000000410109F0E0500000000009F0F05BC709C98009F0D05BC509C08008407A00000000410109F090200025F340101";
                        // } else {
                        //     icc55 = icc55;
                        // }
                        field.setDataStr(icc55);
                    } else {
                        iterator.remove();
                    }
                    break;
                case 60:
                    // TODO
                    break;
                case 61:
                    // TODO
                    break;
                case 62:
                    // TODO
                    break;
                case 63:
                    // TODO
                    break;
                case 64: // 报文鉴别码(MAC)  响应消息中39域为"00"时必选
                    field.setDataStr("0000000000000000");
                    break;
            }
            next = iterator.hasNext();
        }
        return map;
    }


}
